package com.ssc.chain.tcfp.core.client;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author mingjian
 * @version 1.0
 * Create by 2025/7/10 18:00
 */
public class RedisDistributedLock implements DistributedLock  {
    private final StringRedisTemplate redisTemplate;
    private final String lockValue = UUID.randomUUID().toString();

    public RedisDistributedLock(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    private static final String LOCK_SUCCESS = "OK";
    private static final Long RELEASE_SUCCESS = 1L;

    @Override
    public boolean tryLock(String key, long timeoutMs) {
        String lockKey = "lock:" + key;
        String value = lockValue + ":" + Thread.currentThread().getId();
        Boolean success = redisTemplate.opsForValue()
                .setIfAbsent(lockKey, value, timeoutMs, TimeUnit.MILLISECONDS);
        return Boolean.TRUE.equals(success);
    }

    @Override
    public void unlock(String key) {
        String lockKey = "lock:" + key;
        // 释放锁需要保证是自己的锁，使用lua脚本原子释放
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) else return 0 end";
        redisTemplate.execute(
                new DefaultRedisScript<>(script, Long.class),
                Collections.singletonList(lockKey),
                lockValue + ":" + Thread.currentThread().getId());
    }
}
